(function(b) {
  b(CodeMirror);
})(function(b) {
  var C, g, P, p, T = {
    QUERY_DIV: ";",
    ALIAS_KEYWORD: "AS"
  }, d = b.Pos, Q = b.cmpPos;
  function R(r) {
    return Object.prototype.toString.call(r) == "[object Array]";
  }
  function D(r) {
    var e = r.doc.modeOption;
    return e === "awsAt" && (e = "awsAt"), b.resolveMode(e).keywords;
  }
  function K(r) {
    var e = r.doc.modeOption;
    return e === "sql" && (e = "text/x-sql"), b.resolveMode(e).identifierQuote || "`";
  }
  function m(r) {
    return typeof r == "string" ? r : r.text;
  }
  function L(r, e) {
    return R(e) && (e = { columns: e }), e.text || (e.text = r), e;
  }
  function M(r) {
    var e = {};
    if (R(r))
      for (var t = r.length - 1; t >= 0; t--) {
        var a = r[t];
        e[m(a).toUpperCase()] = L(m(a), a);
      }
    else if (r)
      for (var n in r)
        e[n.toUpperCase()] = L(n, r[n]);
    return e;
  }
  function y(r) {
    return C[r.toUpperCase()];
  }
  function E(r) {
    var e = {};
    for (var t in r)
      r.hasOwnProperty(t) && (e[t] = r[t]);
    return e;
  }
  function Y(r, e) {
    var t = r.length, a = m(e).substr(0, t);
    return r.toUpperCase() === a.toUpperCase();
  }
  function x(r, e, t, a) {
    if (t) {
      for (var n in t)
        if (t.hasOwnProperty(n)) {
          var l = t[n];
          l && Y(e, n) && (n.indexOf("@") === -1 ? r.push(a(l.name, null, l.id)) : r.push(a(l.key + " - " + l.title, null, l.key)));
        }
    }
  }
  function _(r) {
    r.charAt(0) == "." && (r = r.substr(1));
    for (var e = r.split(p + p), t = 0; t < e.length; t++)
      e[t] = e[t].replace(new RegExp(p, "g"), "");
    return e.join(p);
  }
  function U(r) {
    for (var e = m(r).split("."), t = 0; t < e.length; t++)
      e[t] = p + // doublicate identifierQuotes
      e[t].replace(new RegExp(p, "g"), p + p) + p;
    var a = e.join(".");
    return typeof r == "string" ? a : (r = E(r), r.text = a, r);
  }
  function V(r, e, t, a) {
    for (var n = !1, l = [], f = e.start, o = !0; o; )
      o = e.string.charAt(0) == ".", n = n || e.string.charAt(0) == p, f = e.start, l.unshift(_(e.string)), e = a.getTokenAt(d(r.line, e.start)), e.string == "." && (o = !0, e = a.getTokenAt(d(r.line, e.start)));
    var c = l.join(".");
    x(t, c, C, function(u) {
      return n ? U(u) : u;
    }), x(t, c, g, function(u) {
      return n ? U(u) : u;
    }), c = l.pop();
    var s = l.join("."), i = !1, A = s;
    if (!y(s)) {
      var v = s;
      s = N(s, a), s !== v && (i = !0);
    }
    var h = y(s);
    return h && h.columns && (h = h.columns), h && x(t, c, h, function(u) {
      var I = s;
      return i == !0 && (I = A), typeof u == "string" ? u = I + "." + u : (u = E(u), u.text = I + "." + u.text), n ? U(u) : u;
    }), f;
  }
  function W(r, e) {
    for (var t = r.split(/\s+/), a = 0; a < t.length; a++)
      t[a] && e(t[a].replace(/[,;]/g, ""));
  }
  function N(r, e) {
    for (var t = e.doc, a = t.getValue(), n = r.toUpperCase(), l = "", f = "", o = [], c = {
      start: d(0, 0),
      end: d(e.lastLine(), e.getLineHandle(e.lastLine()).length)
    }, s = a.indexOf(T.QUERY_DIV); s != -1; )
      o.push(t.posFromIndex(s)), s = a.indexOf(T.QUERY_DIV, s + 1);
    o.unshift(d(0, 0)), o.push(d(e.lastLine(), e.getLineHandle(e.lastLine()).text.length));
    for (var i = null, A = e.getCursor(), v = 0; v < o.length; v++) {
      if ((i == null || Q(A, i) > 0) && Q(A, o[v]) <= 0) {
        c = { start: i, end: o[v] };
        break;
      }
      i = o[v];
    }
    if (c.start)
      for (var h = t.getRange(c.start, c.end, !1), v = 0; v < h.length; v++) {
        var u = h[v];
        if (W(u, function(O) {
          var S = O.toUpperCase();
          S === n && y(l) && (f = l), S !== T.ALIAS_KEYWORD && (l = O);
        }), f)
          break;
      }
    return f;
  }
  b.registerHelper("hint", "atformula", function(r, e) {
    C = M(e && e.tables);
    var t = e && e.defaultTable, a = e && e.disableKeywords;
    g = t && y(t), P = r.keywords ? r.keywords : D(r), p = K(r), t && !g && (g = N(t, r)), g = g || [], g.columns && (g = g.columns);
    var n = r.getCursor(), l = [], f = r.getTokenAt(n), o, c, s;
    if (f.end > n.ch && (f.end = n.ch, f.string = f.string.slice(0, n.ch - f.start)), f.string.match(/^[.`"\w@]\w*$/) ? (s = f.string, o = f.start, c = f.end) : (o = c = n.ch, s = ""), s.length !== 0)
      return s.charAt(0) == "." || s.charAt(0) == p ? o = V(n, f, l, r) : (x(l, s, g, function(i) {
        return { text: i, className: "CodeMirror-hint-table CodeMirror-hint-default-table" };
      }), x(
        l,
        s,
        C,
        function(i) {
          return typeof i == "object" ? i.className = "CodeMirror-hint-table" : i = { text: i, className: "CodeMirror-hint-table" }, i;
        }
      ), a || x(l, s, P, function(i, A, v) {
        return { text: i, className: "CodeMirror-hint-keyword", desc: A, key: v };
      })), { list: l, from: d(n.line, o), to: d(n.line, c) };
  });
});
